# coding=utf-8
from collections import namedtuple

from common.utils import id_generator
from common.utils import track_logging
from common.utils.db import list_object
from common.utils.decorator import sql_wrapper
from common.utils.exceptions import ParamError
from model import AgentPayOrder, AGENT_PAY_STATUS

_LOGGER = track_logging.getLogger(__name__)

BankCard = namedtuple('BankCard', ['bank_code', 'card_no', 'account_name', 'phone_number', 'bank_name', 'identity_card',
                                   'account_province', 'account_city', 'unionpay_no', 'card_num', 'chn_type',
                                   'platform'])


@sql_wrapper
def create_agent_pay_order(operator_id, channel_id, total_fee, bankcard):
    assert isinstance(bankcard, BankCard)
    agent_pay_order = AgentPayOrder()
    agent_pay_order.operator_id = operator_id
    agent_pay_order.channel_id = channel_id
    agent_pay_order.order_no = id_generator.generate_long_id('agentpay')
    agent_pay_order.total_fee = total_fee
    agent_pay_order.bank_code = bankcard.bank_code
    agent_pay_order.card_no = bankcard.card_no
    agent_pay_order.account_name = bankcard.account_name
    agent_pay_order.phone_number = bankcard.phone_number
    agent_pay_order.bank_name = bankcard.bank_name
    agent_pay_order.status = AGENT_PAY_STATUS.CREATED
    agent_pay_order.identity_card = bankcard.identity_card
    agent_pay_order.account_province = bankcard.account_province
    agent_pay_order.account_city = bankcard.account_city
    agent_pay_order.unionpay_no = bankcard.unionpay_no
    agent_pay_order.card_num = bankcard.card_num
    agent_pay_order.chn_type = bankcard.chn_type
    agent_pay_order.platform = bankcard.platform
    agent_pay_order.save()
    return agent_pay_order


@sql_wrapper
def get_agent_pay_order(order_no, with_lock=False):
    if with_lock:
        return AgentPayOrder.query.filter(AgentPayOrder.order_no == order_no).with_lockmode('update').first()
    else:
        return AgentPayOrder.query.filter(AgentPayOrder.order_no == order_no).first()


@sql_wrapper
def checked_agent_pay_success(order_no, auto_commit=True):
    agent_pay = get_agent_pay_order(order_no, True)
    if agent_pay.status != AGENT_PAY_STATUS.SUCCESS:
        raise ParamError('agent pay not success, can not checked')

    agent_pay.status = AGENT_PAY_STATUS.CHECKED
    agent_pay.save(auto_commit=auto_commit)


def update_agent_pay_status_to_submit(order_no, auto_commit=True):
    agent_pay = get_agent_pay_order(order_no, True)
    if agent_pay.status != AGENT_PAY_STATUS.CREATED:
        raise ParamError('agent pay not created, can not submit')

    agent_pay.status = AGENT_PAY_STATUS.SUBMIT
    agent_pay.save(auto_commit=auto_commit)


def set_agent_pay_out_order_no(order_no, out_order_no, auto_commit=True):
    agent_pay = get_agent_pay_order(order_no, True)
    if agent_pay.out_order_no:
        raise ParamError('agent pay had out_order_no')
    agent_pay.out_order_no = out_order_no
    agent_pay.save(auto_commit=auto_commit)


def list_order(query_dct):
    return list_object(query_dct, AgentPayOrder)
